package com.h2cloud.rolling;

/**
 * @author: wulongkai
 * @create: 2023-05-27 14:58
 **/

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.Assert;

import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.YearMonth;
import java.util.*;

public class DateToStartEndOfDay {
    public static Date getStartOfDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static Date getEndOfDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    public static void main(String[] args) throws ParseException {
        Gson gson = new GsonBuilder()
//                .setPrettyPrinting()
//                .serializeNulls()   //在序列化的时候不忽略null值
                .create();

//        Date currentDate = new Date();
//
//        Date startOfDay = getStartOfDay(currentDate);
//        Date endOfDay = getEndOfDay(currentDate);
//
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//
//        System.out.println("Start of Day: " + sdf.format(startOfDay));
//        System.out.println("End of Day: " + sdf.format(endOfDay));
//
//        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMM");
//        Integer month = 202305;
//        Date parse = simpleDateFormat.parse(month + "");
//        Calendar cal1 = getInstance();
//        cal1.setTime(parse);
//        Calendar cal2 = getInstance();
//        cal2.setTime(new Date());
//
//
//        String url = "http://testv3.58v5.cn/NPoPJiHgFeNcP/encryptedfile-0b128b7d/1661941876292333568.png";
//        String substring = url.substring(url.lastIndexOf('.'));
//        System.out.println("substring = " + substring);

        long beginMonth = format2Number(new Date(), "yyyyMM");
        System.out.println("beginMonth = " + beginMonth);

        List<Integer> list = calculateLast12Months(202306);
        System.out.println("list = " + list);

        List<Integer> monthsWindow = getMonthsWindow();
        System.out.println("monthsWindow = " + monthsWindow);

        Map<Integer, Integer> map = new HashMap<>();
        for (Integer integer : monthsWindow) {
            map.put(integer, integer);
        }

        String json = gson.toJson(map);
        System.out.println("json.length() = " + json.length());
        System.out.println("json = " + json);

        Type mapType = TypeToken.getParameterized(Map.class, Integer.class, Integer.class).getType();
        Map<Integer, Integer> map2 = gson.fromJson(json, mapType);

        System.out.println(map2);
        System.out.println("map2.get(202402) = " + map2.get(202402));


    }

    static Long format2Number(Date startDate, String style) {
        String format = format(startDate, style);
        if (StringUtils.isNotEmpty(format)) {
            return Long.parseLong(format);
        }
        throw new RuntimeException("无法将日期转换成数字格式yyyyMM:" + startDate);
    }

    public static String format(Date date, String pattern) {
        if (Objects.isNull(date)) {
            return "";
        }
        SimpleDateFormat sdf;
        if (StringUtils.isNotEmpty(pattern)) {
            sdf = new SimpleDateFormat(pattern);
        } else {
            sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
        return sdf.format(date);
    }

    public static List<Integer> calculateLast12Months(Integer dataPeriod) {
        LocalDateTime now = getLocalDateTimeFromPeriod(dataPeriod);
        List<Integer> last12Months = new ArrayList<>(12);
        for (int i = 0; i < 12; i++) {
            now = now.minusMonths(1);
            last12Months.add(getPeriod(now));
        }
        return last12Months;
    }

    public static LocalDateTime getLocalDateTimeFromPeriod(final Integer period) {
        Assert.notNull(period, "所属期不可以为空");
        String p = String.valueOf(period);
        String year = p.substring(0, 4);
        String month = p.substring(4, 6);
        return LocalDateTime.of(Integer.parseInt(year), Integer.parseInt(month), 1, 0, 0, 0);
    }

    public static Integer getPeriod(final LocalDateTime effectiveDate) {
        int month = effectiveDate.getMonthValue();
        if (month > Month.SEPTEMBER.getValue()) {
            return Integer.parseInt(effectiveDate.getYear() + "" + month);
        }
        return Integer.parseInt(effectiveDate.getYear() + "0" + month);
    }

    private static List<Integer> getMonthsWindow() {
        int beginMonth = 202310;
        int endMonth = getEndMonth(beginMonth);

        int startYear = beginMonth / 100;
        int startMonth = beginMonth % 100;

        int endYear = endMonth / 100;
        int endMonthValue = endMonth % 100;

        YearMonth start = YearMonth.of(startYear, startMonth);
        YearMonth end = YearMonth.of(endYear, endMonthValue);
        YearMonth current = start;
        List<Integer> months = new ArrayList<>();
        while (current.isBefore(end) || current.equals(end)) {
            int year = current.getYear();
            int month = current.getMonthValue();
            months.add(year * 100 + month);
            current = current.plusMonths(1);
        }
        return months;
    }

    private static int getEndMonth(long beginMonth) {
        String begin = String.valueOf(beginMonth);
        String end;
        if (begin.substring(4).startsWith("0")) {
            end = begin.substring(0, 4) + "12";
        } else {
            end = addOne(begin.substring(0, 4)) + "12";
        }
        return Integer.parseInt(end);
    }

    private static String addOne(String str) {
        int i = Integer.parseInt(str) + 1;
        return String.valueOf(i);
    }
}

